#include <iostream>
#include <memory>
#include <vector>
#include<windows.h>
using namespace std;

// ---------------- 接收者 Receiver ----------------
class TV
{
public:
    void turnOn()
    {
        cout << "电视已打开 📺" << endl;
    }
    void turnOff()
    {
        cout << "电视已关闭 🔌" << endl;
    }
    void changeChannel(int channel)
    {
        cout << "切换到频道：" << channel << endl;
    }
};

// ---------------- 命令接口 Command ----------------
class Command
{
public:
    virtual void execute() = 0;
    virtual void undo() {} // 可选实现撤销
    virtual ~Command() = default;
};

// ---------------- 具体命令 ConcreteCommand ----------------
class TurnOnCommand : public Command
{
    shared_ptr<TV> tv;

public:
    TurnOnCommand(shared_ptr<TV> t) : tv(t) {}
    void execute() override { tv->turnOn(); }
    void undo() override { tv->turnOff(); }
};

class TurnOffCommand : public Command
{
    shared_ptr<TV> tv;

public:
    TurnOffCommand(shared_ptr<TV> t) : tv(t) {}
    void execute() override { tv->turnOff(); }
    void undo() override { tv->turnOn(); }
};

class ChangeChannelCommand : public Command
{
    shared_ptr<TV> tv;
    int channel;
    int prevChannel;

public:
    ChangeChannelCommand(shared_ptr<TV> t, int ch) : tv(t), channel(ch), prevChannel(1) {}
    void execute() override
    {
        cout << "(记录原频道：" << prevChannel << ")" << endl;
        tv->changeChannel(channel);
        prevChannel = channel;
    }
    void undo() override
    {
        cout << "撤销换台操作，回到频道：" << prevChannel << endl;
        tv->changeChannel(prevChannel);
    }
};

// ---------------- 调用者 Invoker ----------------
class RemoteControl
{
    shared_ptr<Command> command;

public:
    void setCommand(shared_ptr<Command> cmd) { command = cmd; }
    void pressButton() { command->execute(); }
    void pressUndo() { command->undo(); }
};

// ---------------- 客户端 Client ----------------
int main()
{
    SetConsoleOutputCP(65001);

    auto tv = make_shared<TV>();
    auto onCommand = make_shared<TurnOnCommand>(tv);
    auto offCommand = make_shared<TurnOffCommand>(tv);
    auto channelCommand = make_shared<ChangeChannelCommand>(tv, 5);

    RemoteControl remote;

    // 打开电视
    remote.setCommand(onCommand);
    remote.pressButton();

    // 换频道
    remote.setCommand(channelCommand);
    remote.pressButton();

    // 关闭电视
    remote.setCommand(offCommand);
    remote.pressButton();

    // 撤销上一个操作
    remote.pressUndo();

    return 0;
}
